/**
 * echarts组件类： 坐标轴
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *
 * 直角坐标系中坐标轴数组，数组中每一项代表一条横轴（纵轴）坐标轴。
 * 标准（1.0）中规定最多同时存在2条横轴和2条纵轴
 *    单条横轴时可指定安放于grid的底部（默认）或顶部，2条同时存在时则默认第一条安放于底部，第二天安放于顶部
 *    单条纵轴时可指定安放于grid的左侧（默认）或右侧，2条同时存在时则默认第一条安放于左侧，第二天安放于右侧。
 * 坐标轴有两种类型，类目型和数值型（区别详见axis）：
 *    横轴通常为类目型，但条形图时则横轴为数值型，散点图时则横纵均为数值型
 *    纵轴通常为数值型，但条形图时则纵轴为类目型。
 *
 */


var Base = require('./base');
var LineShape = require('zrender/shape/Line');
var ecConfig = require('../config');
var ecData = require('../util/ecData');
var zrUtil = require('zrender/tool/util');
var zrColor = require('zrender/tool/color');
/**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 图表选项
     *     @param {string=} option.xAxis.type 坐标轴类型，横轴默认为类目型'category'
     *     @param {string=} option.yAxis.type 坐标轴类型，纵轴默认为类目型'value'
     * @param {Object} component 组件
     * @param {string} axisType 横走or纵轴
     */
function Axis(ecTheme, messageCenter, zr, option, myChart, axisType) {
    Base.call(this, ecTheme, messageCenter, zr, option, myChart);
    this.axisType = axisType;
    this._axisList = [];
    this.refresh(option);
}
Axis.prototype = {
    type: ecConfig.COMPONENT_TYPE_AXIS,
    axisBase: {
        // 轴线
        _buildAxisLine: function () {
            var lineWidth = this.option.axisLine.lineStyle.width;
            var halfLineWidth = lineWidth / 2;
            var axShape = {
                _axisShape: 'axisLine',
                zlevel: this.getZlevelBase(),
                z: this.getZBase() + 3,
                hoverable: false
            };
            var grid = this.grid;
            switch (this.option.position) {
            case 'left':
                axShape.style = {
                    xStart: grid.getX() - halfLineWidth,
                    yStart: grid.getYend(),
                    xEnd: grid.getX() - halfLineWidth,
                    yEnd: grid.getY(),
                    lineCap: 'round'
                };
                break;
            case 'right':
                axShape.style = {
                    xStart: grid.getXend() + halfLineWidth,
                    yStart: grid.getYend(),
                    xEnd: grid.getXend() + halfLineWidth,
                    yEnd: grid.getY(),
                    lineCap: 'round'
                };
                break;
            case 'bottom':
                axShape.style = {
                    xStart: grid.getX(),
                    yStart: grid.getYend() + halfLineWidth,
                    xEnd: grid.getXend(),
                    yEnd: grid.getYend() + halfLineWidth,
                    lineCap: 'round'
                };
                break;
            case 'top':
                axShape.style = {
                    xStart: grid.getX(),
                    yStart: grid.getY() - halfLineWidth,
                    xEnd: grid.getXend(),
                    yEnd: grid.getY() - halfLineWidth,
                    lineCap: 'round'
                };
                break;
            }
            var style = axShape.style;
            if (this.option.name !== '') {
                // 别帮我代码规范
                style.text = this.option.name;
                style.textPosition = this.option.nameLocation;
                style.textFont = this.getFont(this.option.nameTextStyle);
                if (this.option.nameTextStyle.align) {
                    style.textAlign = this.option.nameTextStyle.align;
                }
                if (this.option.nameTextStyle.baseline) {
                    style.textBaseline = this.option.nameTextStyle.baseline;
                }
                if (this.option.nameTextStyle.color) {
                    style.textColor = this.option.nameTextStyle.color;
                }
            }
            style.strokeColor = this.option.axisLine.lineStyle.color;
            style.lineWidth = lineWidth;
            // 亚像素优化
            if (this.isHorizontal()) {
                // 横向布局，优化y
                style.yStart = style.yEnd = this.subPixelOptimize(style.yEnd, lineWidth);
            } else {
                // 纵向布局，优化x
                style.xStart = style.xEnd = this.subPixelOptimize(style.xEnd, lineWidth);
            }
            style.lineType = this.option.axisLine.lineStyle.type;
            axShape = new LineShape(axShape);
            this.shapeList.push(axShape);
        },
        _axisLabelClickable: function (clickable, axShape) {
            if (clickable) {
                ecData.pack(axShape, undefined, -1, undefined, -1, axShape.style.text);
                axShape.hoverable = true;
                axShape.clickable = true;
                axShape.highlightStyle = {
                    color: zrColor.lift(axShape.style.color, 1),
                    brushType: 'fill'
                };
                return axShape;
            } else {
                return axShape;
            }
        },
        refixAxisShape: function (zeroX, zeroY) {
            if (!this.option.axisLine.onZero) {
                return;
            }
            var tickLength;
            if (this.isHorizontal() && zeroY != null) {
                // 横向布局调整纵向y
                for (var i = 0, l = this.shapeList.length; i < l; i++) {
                    if (this.shapeList[i]._axisShape === 'axisLine') {
                        this.shapeList[i].style.yStart = this.shapeList[i].style.yEnd = this.subPixelOptimize(zeroY, this.shapeList[i].stylelineWidth);
                        this.zr.modShape(this.shapeList[i].id);
                    } else if (this.shapeList[i]._axisShape === 'axisTick') {
                        tickLength = this.shapeList[i].style.yEnd - this.shapeList[i].style.yStart;
                        this.shapeList[i].style.yStart = zeroY - tickLength;
                        this.shapeList[i].style.yEnd = zeroY;
                        this.zr.modShape(this.shapeList[i].id);
                    }
                }
            }
            if (!this.isHorizontal() && zeroX != null) {
                // 纵向布局调整横向x
                for (var i = 0, l = this.shapeList.length; i < l; i++) {
                    if (this.shapeList[i]._axisShape === 'axisLine') {
                        this.shapeList[i].style.xStart = this.shapeList[i].style.xEnd = this.subPixelOptimize(zeroX, this.shapeList[i].stylelineWidth);
                        this.zr.modShape(this.shapeList[i].id);
                    } else if (this.shapeList[i]._axisShape === 'axisTick') {
                        tickLength = this.shapeList[i].style.xEnd - this.shapeList[i].style.xStart;
                        this.shapeList[i].style.xStart = zeroX;
                        this.shapeList[i].style.xEnd = zeroX + tickLength;
                        this.zr.modShape(this.shapeList[i].id);
                    }
                }
            }
        },
        getPosition: function () {
            return this.option.position;
        },
        isHorizontal: function () {
            return this.option.position === 'bottom' || this.option.position === 'top';
        }
    },
    /**
         * 参数修正&默认值赋值，重载基类方法
         * @param {Object} opt 参数
         */
    reformOption: function (opt) {
        // 不写或传了个空数值默认为数值轴
        if (!opt || opt instanceof Array && opt.length === 0) {
            opt = [{ type: ecConfig.COMPONENT_TYPE_AXIS_VALUE }];
        } else if (!(opt instanceof Array)) {
            opt = [opt];
        }
        // 最多两条，其他参数忽略
        if (opt.length > 2) {
            opt = [
                opt[0],
                opt[1]
            ];
        }
        if (this.axisType === 'xAxis') {
            // 横轴位置默认配置
            if (!opt[0].position || opt[0].position != 'bottom' && opt[0].position != 'top') {
                opt[0].position = 'bottom';
            }
            if (opt.length > 1) {
                opt[1].position = opt[0].position === 'bottom' ? 'top' : 'bottom';
            }
            for (var i = 0, l = opt.length; i < l; i++) {
                // 坐标轴类型，横轴默认为类目型'category'
                opt[i].type = opt[i].type || 'category';
                // 标识轴类型&索引
                opt[i].xAxisIndex = i;
                opt[i].yAxisIndex = -1;
            }
        } else {
            // 纵轴位置默认配置
            if (!opt[0].position || opt[0].position != 'left' && opt[0].position != 'right') {
                opt[0].position = 'left';
            }
            if (opt.length > 1) {
                opt[1].position = opt[0].position === 'left' ? 'right' : 'left';
            }
            for (var i = 0, l = opt.length; i < l; i++) {
                // 坐标轴类型，纵轴默认为数值型'value'
                opt[i].type = opt[i].type || 'value';
                // 标识轴类型&索引
                opt[i].xAxisIndex = -1;
                opt[i].yAxisIndex = i;
            }
        }
        return opt;
    },
    /**
         * 刷新
         */
    refresh: function (newOption) {
        var axisOption;
        if (newOption) {
            this.option = newOption;
            if (this.axisType === 'xAxis') {
                this.option.xAxis = this.reformOption(newOption.xAxis);
                axisOption = this.option.xAxis;
            } else {
                this.option.yAxis = this.reformOption(newOption.yAxis);
                axisOption = this.option.yAxis;
            }
            this.series = newOption.series;
        }
        var CategoryAxis = require('./categoryAxis');
        var ValueAxis = require('./valueAxis');
        var len = Math.max(axisOption && axisOption.length || 0, this._axisList.length);
        for (var i = 0; i < len; i++) {
            if (this._axisList[i]    // 已有实例
&& newOption    // 非空刷新
&& (!axisOption[i] || this._axisList[i].type != axisOption[i].type)    // 类型不匹配
) {
                this._axisList[i].dispose && this._axisList[i].dispose();
                this._axisList[i] = false;
            }
            if (this._axisList[i]) {
                this._axisList[i].refresh && this._axisList[i].refresh(axisOption ? axisOption[i] : false, this.series);
            } else if (axisOption && axisOption[i]) {
                this._axisList[i] = axisOption[i].type === 'category' ? new CategoryAxis(this.ecTheme, this.messageCenter, this.zr, axisOption[i], this.myChart, this.axisBase) : new ValueAxis(this.ecTheme, this.messageCenter, this.zr, axisOption[i], this.myChart, this.axisBase, this.series);
            }
        }
    },
    /**
         * 根据值换算位置
         * @param {number} idx 坐标轴索引0~1
         */
    getAxis: function (idx) {
        return this._axisList[idx];
    },
    getAxisCount: function () {
        return this._axisList.length;
    },
    clear: function () {
        for (var i = 0, l = this._axisList.length; i < l; i++) {
            this._axisList[i].dispose && this._axisList[i].dispose();
        }
        this._axisList = [];
    }
};
zrUtil.inherits(Axis, Base);
require('../component').define('axis', Axis);
module.exports = Axis || module.exports;;